#include <length.h>
#include "memBlocks.h"

template<typename T>
static _ptlong _PopGroup(_ptlong up,_ptlong down, _ptlong size,T fun)
{
  return ((down != 0)
	  ? ((down - up >= (_ptlong)size)
	     ? up
	     : (fun(up,down),_PopGroup(up,down,size,fun)))
	  : (~0));
}

_ptlong* memBlocks::PopGroup(_ptlong blocknum)
{
  set<memBlock>::iterator it = blocks.begin();
  _ptlong _size = blocknum*blockSize;
  if(it == blocks.end())
    {
      return (_ptlong*)up;
    }
  _ptlong _up = ((*it).a == up
		 ? ((*it++).b)
		 : up);
  _ptlong _down = (it == blocks.end()
		   ? down
		   : (*it).a);
  _ptlong ret;
  return (_ptlong*)(ret = _PopGroup(_up,_down,_size,[&](_ptlong& up_,_ptlong& down_)->void
		   {
		     if (it == blocks.end())
		       {
			 down_ = 0;
		       }
		     else
		       {
			 up_ = (*it).b;
			 down_ = (++it == blocks.end()
				  ? down
				  : (*it).a);
		       }
		   }) != (~0)
	  ? (blocks.insert(memBlock(ret,ret + _size)),(_ptlong)ret)
	  : NULL);
  
}

/*
//The function has problem
_ptlong PushGroup(_ptlong* addr,_ptlong blocknum)
{
  memBlock rel(addr,((_ptlong)addr) + blocknum * blockSize);
  for(set<memBlock>::iterator it = blocks.find(rel);it != blocks.end();it = blocks.find(rel))
    {
      if(it != blocks.end())
	{
	  if(rel.b - 1 > (*it).b)
	    blocks.insert(memBlock(rel.b - 1,(*it).b));
	  if(rel.a + 1 < (*it).a)
	    blocks.insert(memBlock((*it).a,rel.a + 1));
	  
	  blocks.erase(it);
	  
	}
    }
}

*/
_ptlong memBlocks::PushGroup(_ptlong* addr)
{
  memBlock rel(addr,addr);
  blocks.erase(blocks.find(rel));
}
